home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.004 / FGUSER15.TXT < prev    next >
Text File  |  1995-05-29  |  24KB  |  602 lines

  1.                                Using the Editor
  2.  
  3.                                   "An ass loaded with gold climbs to
  4.                                    the top of the castle"
  5.                                                   English Proverb
  6.  
  7. Introduction
  8.  
  9.           One of the most requested tools over the past few years has
  10.      been a plug-in editor which you can easily incorporate into an
  11.      application. Well here it is. Rather than implement a basic little
  12.      line editor, we decide to endow Gold with a beefy "Arnold" editor
  13.      that includes the following features:
  14.  
  15.           Automatic dynamic word wrap
  16.           Clipboard support allowing for cut/copy and paste
  17.           Full mouse support
  18.           Support for optional headers and footers
  19.           Hooks to allow customization
  20.  
  21.  
  22.      Figure 15.1
  23.      Edit Windows
  24.  
  25.  
  26. Basic Principles
  27.  
  28.           Many of the principles used with the editing functions are
  29.      identical with those used for listing and browsing data (discussed
  30.      in the last chapter).
  31.  
  32.           Gold needs to know the main properties of the data and the
  33.      characteristics of the window in which the data will be displayed.
  34.      For example, before an edit window can be displayed, Gold needs to
  35.      know some of the following information:
  36.  
  37.           What type of data is to be displayed, e.g. a single linked
  38.                list, double linked list, array, etc.
  39.           Where the data is stored, i.e. the name of the variable.
  40.           The dimensions and style of the window.
  41.           The window title.
  42.           Any optional memo headers and footers.
  43.           What colors are to be used.
  44.  
  45.           You define all these memo characteristics by creating a
  46.      variable (of type MemoCfg, for memo configuration), initializing
  47.      the variable, and then setting various components of the variable
  48.      to define your specific needs.
  49.  
  50.           In other words, to display a memo in a window you need at
  51.      least two variables: a list configuration variable, and a variable
  52.      used to store the data.
  53.  
  54.           Having configured the MemoCfg variable and loaded the data the
  55.      following function can be used to provide an edit window:
  56.  
  57.      RunMemo(var MemoDetails: MemoCfg; Tit:StrScreen);
  58.  
  59.      Displays the data identified in MemoDetails in an edit window.
  60.  
  61.  
  62. Defining the Memo Configuration
  63.  
  64.           The key to displaying a memo window is to declare a variable
  65.      of type MemoCfg, and then call Gold functions to set MemoCfg to
  66.      meet your specific needs.
  67.  
  68. Initializing MemoCfg
  69.  
  70.           Always, always, always call InitMemoCfg to initialize the
  71.      MemoCfg variable before calling the other memo procedures and
  72.      functions.
  73.  
  74.      InitMemoCfg(var MemoDetails: MemoCfg);
  75.  
  76.      Initializes a memo configuration variable.
  77.  
  78.      Assigning the Data Source
  79.  
  80.           Having initialized the MemoCfg variable you then need to
  81.      update the variable with information about the memo data source.
  82.      Gold can display the contents of a SingleLL, DoubleLL, or a string
  83.      array. Dependent upon your data source, you would call one of the
  84.      following procedures to update the MemoCfg variable with the data
  85.      source details:
  86.  
  87.      MemoAssignSLL(var MemoDetails: MemoCfg; var MemoSource: SingleLL);
  88.  
  89.           Sets the MemoCfg variable data source as a single linked list
  90.      stored in the variable MemoSource.
  91.  
  92.      MemoAssignDLL(var MemoDetails: MemoCfg; var MemoSource: DoubleLL);
  93.  
  94.           Sets the MemoCfg variable data source as a double linked list
  95.      stored in the variable MemoSource.
  96.  
  97.      MemoAssignArray(var MemoDetails: MemoCfg; var MemoSource;
  98.                                         StrLen:Byte;ArrayElements:byte);
  99.  
  100.           Sets the MemoCfg variable data source as a string array stored
  101.      in the variable MemoSource. The last two parameters define the
  102.      length of each string in the array, and the number of elements in
  103.      the array, respectively.
  104.  
  105. Setting Window Properties
  106.  
  107.           When the MemoCfg variable is initialized, the window
  108.      properties (such as the window position and dimensions) are set to
  109.      some standard defaults. If these defaults are not appropriate, you
  110.      can customize them with the following two procedures
  111.  
  112.      MemoSetWin(var MemoDetails: MemoCfg; X1,Y1,X2,Y2:integer;
  113.                                                          Style:byte);
  114.  
  115.           Defines the upper left and lower right corners of the window
  116.      along with the window style. (Refer to chapter 4 for a discussion
  117.      of window styles.)
  118.  
  119.      MemoSetGaps(var MemoDetails: MemoCfg;
  120.                                 LeftGap,RightGap,BotGap,TopGap: byte);
  121.  
  122.           This procedure allows you to set the gap or whitespace area
  123.      around the memo body. The editable data does not need to fill the
  124.      entire window.
  125.  
  126.  
  127.           If you want to change the window defaults, update the
  128.      following variables: MemoVars.X1, MemoVars.Y1, MemoVars.X2,
  129.      MemoVars.Y2, and MemoVars.WiStyle.
  130.  
  131. Setting the Window Colors
  132.  
  133.           As usual, the default colors are defined in the TINT
  134.      structure, and the following elements pertain to memo windows:
  135.  
  136.           MemoHi,
  137.           MemoNorm,
  138.           MemoBlock,
  139.           MemoScrollbarHi,
  140.           MemoScrollbarNorm,
  141.           MemoBorder1,
  142.           MemoBorder2,
  143.           MemoBorderOff,
  144.           MemoTitle,
  145.           MemoHeaders,
  146.           MemoIcons,
  147.  
  148.           You can modify the defaults (used by any new memo windows
  149.      initialized after the modification) by using the standard
  150.      GoldSetColor procedure.
  151.  
  152.           You can modify the colors of a specific memo window by using
  153.      the following function:
  154.  
  155.      MemoSetColor(var MemoDetails: MemoCfg; A:TintElement;C:byte);
  156.  
  157.      Sets the color of one of the elements of a memo window.
  158.  
  159.           The following code is an extract from DEMMEM6.PAS which
  160.      customizes the list display colors:
  161.  
  162.           procedure CustomizeColors;
  163.           {}
  164.           begin
  165.              MemoSetColor(MemoSettings,MemoHi,
  166.                           LightGrayonMagenta);
  167.              MemoSetColor(MemoSettings,MemoBlock,YellowOnBlue);
  168.              MemoSetColor(MemoSettings,MemoNorm,YellowOnMagenta);
  169.              MemoSetColor(MemoSettings,MemoScrollbarHi,
  170.                           WhiteOnMagenta);
  171.              MemoSetColor(MemoSettings,MemoScrollbarNorm,
  172.                           WhiteOnMagenta);
  173.              MemoSetColor(MemoSettings,MemoBorder1,
  174.                           YellowOnMagenta);
  175.              MemoSetColor(MemoSettings,MemoBorder2,
  176.                           YellowOnMagenta);
  177.              MemoSetColor(MemoSettings,MemoBorderOff,
  178.                           BlackOnMagenta);
  179.              MemoSetColor(MemoSettings,MemoTitle,WhiteOnMagenta);
  180.              MemoSetColor(MemoSettings,MemoHeaders,
  181.                                          GreenOnMagenta);
  182.              MemoSetColor(MemoSettings,MemoIcons,
  183.                           LightCyanOnMagenta);
  184.           end; { CustomizeColors }
  185.  
  186. Using Headers and Footers
  187.  
  188.           Memo windows support multi-line headers and footers. Out of
  189.      the box, Gold limits the number of heading lines and footer lines
  190.      to 4, but you can change the number by assigning a different value
  191.      to the constants ListMaxHeaders and ListMaxFooters declared in
  192.      GOLDLIST.
  193.  
  194.           To minimize memory usage, all headers and footers must be
  195.      stored as string variables in your program. (Gold simply stores a
  196.      pointer to the variable.)
  197.  
  198.           The following six procedures can be used to manage the headers
  199.      and footers:
  200.  
  201.      MemoAssignHeader(var MemoDetails: MemoCfg; Line:byte; var
  202.                                                        Heading:string);
  203.  
  204.           Sets the memo configuration variable to display a string as a
  205.      header. A string variable must be passed -- a string literal will
  206.      not be accepted. The line must be a value in the range 1 to
  207.      ListMaxHeaders (which defaults to 4).
  208.  
  209.      MemoAssignFooter(var MemoDetails: MemoCfg; Line:byte; var
  210.                                                    Footnote:string);
  211.  
  212.           Sets the memo configuration variable to display a string as a
  213.      footer. A string variable must be passed -- a string literal will
  214.      not be accepted. The line must be a value in the range 1 to
  215.      ListMaxFooters (which defaults to 4).
  216.  
  217.      MemoRemoveHeader(var MemoDetails: MemoCfg; Line:byte);
  218.  
  219.           Removes a header line which was previously assigned with
  220.      MemoAssignHeader.
  221.  
  222.      MemoRemoveFooter(var MemoDetails: MemoCfg; Line:byte);
  223.  
  224.           Removes a header line which was previously assigned with
  225.      MemoAssignFooter.
  226.  
  227.      MemoScrollHeader(var MemoDetails: MemoCfg; On:boolean);
  228.  
  229.           Pass TRUE if the headings should be scrolled right and left
  230.      when the user scrolls the memo body right and left, or FALSE if the
  231.      header should remain fixed.
  232.  
  233.      MemoScrollFooter(var MemoDetails: MemoCfg; On:boolean);
  234.  
  235.           Pass TRUE if the headings should be scrolled right and left
  236.      when the user scrolls the memo body right and left, or FALSE if the
  237.      header should remain fixed
  238.  
  239.           You can automatically center a header or footer by prefixing
  240.      the string with the ^ character.
  241.  
  242.           Refer to the demo file DEMMEM1.PAS for an example of a memo
  243.      with a heading.
  244.  
  245. Controlling Word Wrap
  246.  
  247.           IMPORTANT NOTE: The GOLDFLAG.INC file includes a conditional
  248.      compiler directive named WORDWRAP. This compiler directive must be
  249.      enabled (i.e. there should be no spaces either side of the $ symbol
  250.      in the {$DEFINE statement) if your program is to support word
  251.      wrapping.
  252.  
  253.           Gold can be configured to edit with or without automatic word
  254.      wrapping. When word wrapping is disabled, the editor functions like
  255.      a normal text editor, e.g. just like DOS' EDIT program. By default,
  256.      word wrapping is enabled, but the following procedure controls the
  257.      word wrapping state:
  258.  
  259.      MemoSetWordWrap(var MemoDetails: MemoCfg; On:boolean);
  260.  
  261.      Pass TRUE to enable word wrapping and FALSE to disable it.
  262.  
  263.           Gold word wraps all text in the current paragraph. You
  264.      indicate the end of a paragraph by inserting an end of paragraph
  265.      character in the text stream. This character is defined in the
  266.      GOLDMEMO unit by the variable MemoVars.EndofParaCode. The code will
  267.      default to char(20) and is displayed as "". This same code will be
  268.      inserted into the text during an edit session when the user presses
  269.      the Enter key.
  270.  
  271.           Before the text is initially displayed at the beginning of a
  272.      RunMemo session, Gold will automatically wrap the text. It is very
  273.      important that the source text includes embedded end of paragraph
  274.      codes where appropriate. Otherwise, Gold will assume the entire
  275.      stream is one big happy paragraph!
  276.  
  277.           Listed below is an extract from DEMMEM1.PAS which shows the
  278.      text stream being created. Notice the embedded end of paragraph
  279.      codes inserted at strategic places in the text.:
  280.  
  281.           procedure BuildSLL;
  282.           {}
  283.           var I: integer;
  284.           begin
  285.              InitSLLStr(TextData);
  286.              I := 0;
  287.              SLLSetActiveList(TextData);
  288.              inc(I,SLLAddStr('Turbo Pascal with Objects ...'));
  289.              inc(I,SLLAddStr('programming system for DOS...'));
  290.              inc(I,SLLAddStr('development.Features DOS...'));
  291.              inc(I,SLLAddStr('application frameworks; wo...' ));
  292.              inc(I,SLLAddStr('create DOS, Windows Dynamic ...'));
  293.              inc(I,SLLAddStr('across platforms.Better ...'));
  294.              inc(I,SLLAddStr('with the award-winning Tech....'));
  295.              if I <> 0 then
  296.              begin
  297.                 PromptOK(' ERROR ','Not enough memory !');
  298.                 halt;
  299.              end;
  300.           end; {BuildSLL}
  301.  
  302.  
  303.           If you want to display an empty window with no initial text,
  304.      you must (as a minimum) assign one end of paragraph marker to the
  305.      text stream -- this is similar to many word processors where a new
  306.      document always contains an end of document symbol.
  307.  
  308.           The following code is an extract from DEMMEM2.PAS which
  309.      attempts to load the source text from a file. If the file load
  310.      fails, a single end of paragraph marker is assigned to the text:
  311.  
  312.           procedure BuildSLL;
  313.           {}
  314.           begin
  315.              InitSLLStr(TextData);
  316.              SLLSetActiveList(TextData);
  317.              if SLLLoadFromFile(TextFileName) <> 0 then {bad}
  318.                 if SLLAddStr(MemoVars.EndofParaCode) <> 0 then
  319.                 begin
  320.                    PromptOK(' ERROR ','Not enough memory');
  321.                    halt;
  322.                 end;
  323.           end; {BuildSLL}
  324.  
  325. Using the Clipboard
  326.  
  327.           That's right, Gold edit session support an internal clipboard
  328.      enabling cut and paste operations!
  329.  
  330.           IMPORTANT NOTE: The GOLDFLAG.INC file includes a conditional
  331.      compiler directive named CUTANDPASTE. This compiler directive must
  332.      be enabled (i.e. there should be no spaces either side of the $
  333.      symbol in the {$DEFINE statement) if your program is to support cut
  334.      and paste.
  335.  
  336.           Having said that there is support for cut and paste, there is
  337.      not a lot left to say. Gold is initially configured to support
  338.      standard key operations like Shift-Del and Ctrl-Ins. These cut and
  339.      paste keystrokes are defined in the MemoVars global variable, and
  340.      you may modify them to support custom keystrokes for copy and paste
  341.      operations. List below is an extract from the initialization
  342.      procedure which defines these keystrokes:
  343.  
  344.           procedure MemoDefaultSettings;
  345.           {}
  346.           begin
  347.              with MemoVars do
  348.              begin
  349.                 DeltoScrapKey := 263;   {Shift-Del}
  350.                 DelBlockKey := 339;     {Del}
  351.                 CopyToScrapkey := 260;  {Ctrl-Ins}
  352.                 InsfromScrapKey := 261; {Shift-Ins}
  353.                 MarkBlockStartKey := 321; {F7}
  354.                 MarkBlockEndKey := 322; {F8}
  355.                 HideBlockKey := 2;      {Ctrl-B}
  356.              end;
  357.           end;
  358.  
  359. Customizing General Edit Keystrokes
  360.  
  361.           In the last section you learned how to customize the
  362.      keystrokes related to the cut and paste operations. List below are
  363.      some other keystrokes which are defined in the global variable
  364.      MemoVars. You may assign new values to any of these keystrokes.
  365.  
  366.           procedure MemoDefaultSettings;
  367.           {}
  368.           begin
  369.              with MemoVars do
  370.              begin
  371.                 WordRightKey := 372;    {Ctrl-Right}
  372.                 WordLeftKey := 371;     {Ctrl-Left}
  373.                 TopOfWindowKey := 375;  {Ctrl-Home}
  374.                 BotOfWindowKey := 373;  {Ctrl-End}
  375.                 TopofMemoKey := 388;    {Ctrl-PgUp}
  376.                 BotofMemoKey := 374;    {Ctrl-PgDn}
  377.                 EndEditKey := 324;      {F10}
  378.                 EscEditKey := 27;       {Esc}
  379.              end;
  380.           end;
  381.  
  382. Determining the Dirty State
  383.  
  384.           Each MemoCfg variable keeps track of whether the data has been
  385.      edited. When the variable is initialized (using InitMemoCfg) the
  386.      state is set to FALSE, i.e. the memo has not been edited. Gold will
  387.      automatically set the dirty flag to true if the data is edited in
  388.      any way.
  389.  
  390.           The following two procedures can be used to get and set the
  391.      state of the dirty flag:
  392.  
  393.      MemoIsDirty(var MemoDetails: MemoCfg):boolean;
  394.  
  395.      Returns TRUE if the memo has been edited.
  396.  
  397.      MemoSetDirty(var MemoDetails: MemoCfg; On:boolean);
  398.  
  399.           Sets the dirty flag which indicates whether or not the data
  400.      has been edited.
  401.  
  402.           The demo files DEMMEM2.PAS and DEMMEM5.PAS use these functions
  403.      during file save operations.
  404.  
  405. Using Memo Hooks
  406.  
  407.           Gold provides two different hooks for customizing memo
  408.      windows: the character hook and the hind hook.
  409.  
  410. The Character Hook
  411.  
  412.           A character hook is a procedure which is called every time a
  413.      key is pressed or a mouse button is clicked while a memo window has
  414.      focus. The hooked procedure is called before the key is processed
  415.      by Gold. The hook is particularly useful for trapping special keys
  416.      like F1 for help, or Ctrl-Y to delete a file, for example.
  417.  
  418.           All you have to do is create a procedure following some
  419.      specific rules, and then call the MemoAssignCharHook procedure to
  420.      instruct Gold to call your procedure every time a key is pressed.
  421.  
  422.           For a procedure to be eligible as a character hook it must
  423.      adhere to the following rules:
  424.  
  425.           The procedure must be declared as a far procedure at the root
  426.           level. Refer to the section Understanding Hooks in Chapter 3
  427.           for further information.
  428.  
  429.           The procedure must be declared with four parameters. The first
  430.           parameter is of type MemoCfgPtr, followed by one variable
  431.           parameter of type word and two variable parameters of type
  432.           byte. These parameters identify the MemoCfg variable used to
  433.           display the memo along with the user input, i.e. the Key, X
  434.           and Y.
  435.  
  436.      The following procedure declaration follows these rules:
  437.  
  438.           {$F+}
  439.           procedure MyCharHook(MP: MemoCfgPtr; var Code:word;var
  440.                                                           X,Y:byte);
  441.           begin
  442.              {some code}
  443.           end; {MyCharHook}
  444.           {$F-}
  445.  
  446.           The following procedure is then called to instruct Gold to
  447.      call your procedure after each input:
  448.  
  449.      MemoAssignCharHook(var MemoDetails: MemoCfg; Proc:MemoCharHook);
  450.  
  451.           Instructs Gold to call the specified procedure before
  452.      processing each user input to a memo window.
  453.  
  454.           If, subsequently, you want to remove the character hook,
  455.      execute the following procedure:
  456.  
  457.      MemoRemoveCharHook(var MemoDetails: MemoCfg);
  458.  
  459.           Removes a list character which was previously assigned with
  460.      MemoAssignCharHook.
  461.  
  462.  
  463.           The demo file DEMMEM7.PAS illustrates a character hook
  464.      providing Ctrl-Y line deletion support.
  465.  
  466. The Hind Hook
  467.  
  468.           A memo hook is similar to a character hook, except the hook is
  469.      called after an input has been processed by Gold. If you want to
  470.      write some additional information to the screen based on the
  471.      cursor, you should take advantage of the hind hook.
  472.  
  473.           For a procedure to be eligible as a hind hook it must adhere
  474.      to the following rules:
  475.  
  476.           The procedure must be declared as a far procedure at the root
  477.           level. Refer to the section Understanding Hooks in Chapter 3
  478.           for further information.
  479.  
  480.           The procedure must be declared with one parameter of type
  481.           MemoCfgPtr.
  482.  
  483.      The following procedure declaration follows these rules:
  484.  
  485.           {$F+}
  486.           procedure MyHineyHook(MemoDetailsPtr:MemoCfgPtr);
  487.           begin
  488.              {some code}
  489.           end; {MyHineyHook}
  490.           {$F-}
  491.  
  492.           The following procedure is then called to instruct Gold to
  493.      call your procedure after each input:
  494.  
  495.      MemoAssignHindHook(var MemoDetails: MemoCfg; Proc:MemoHindHook));
  496.  
  497.           Instructs Gold to call the specified procedure after
  498.      processing each user input to a list window, and once when the
  499.      window is first displayed.
  500.  
  501.           The variable parameter which is passed to the procedure is
  502.      actually a pointer to the MemoCfg variable which is being used by
  503.      the memo. You can de-reference the pointer to access the variable,
  504.      for example:
  505.  
  506.           Total := MemoDetails^.TotalNodes
  507.  
  508.           If, subsequently, you want to remove the hind hook, execute
  509.      the following procedure:
  510.  
  511.      MemoRemoveHindHook(var MemoDetails:MemoCfg);
  512.  
  513.           Removes a memo hind which was previously assigned with
  514.      MemoAssignHindHook.
  515.  
  516.           The demo file DEMMEM8.PAS shows a hind hook used to displayed
  517.      the cursor position, and indicates when the file has been modified.
  518.  
  519. Launching Memos on the Desktop
  520.  
  521.           The desktop equivalent of RunMemo, is LaunchMemo which is
  522.      described as follows:
  523.  
  524.      LaunchMemo(var MemoDetails: MemoCfg;Tit:StrScreen;
  525.                                         CloseProc:MemoCloseProc): byte;
  526.  
  527.           Adds a memo window to the desktop. The function returns the
  528.      number (or handle) of the newly created window.
  529.  
  530.           Like its Run counter part, the LaunchMemo function is passed a
  531.      MemoCfg variable and a title. Additionally, LaunchMemo is passed a
  532.      close function as a third parameter. This close function is called
  533.      whenever the user tries to close the window on the desktop, and it
  534.      provides you with an opportunity to do any housekeeping (such as
  535.      disposing of linked lists) before the window is closed.
  536.  
  537.           For a function to be eligible as a memo close hook it must
  538.      adhere to the following rules:
  539.  
  540.           The function must be declared as a far function at the root
  541.           level. Refer to the section Understanding Hooks in Chapter 4
  542.           for further information.
  543.  
  544.           The function must be declared with one parameter of type
  545.           MemoCfgPtr, and one integer. The function must return a
  546.           boolean value.
  547.  
  548.      The following procedure declaration follows these rules:
  549.  
  550.           {$F+}
  551.           function GoodbyeList(var MCP: MemoCfgPtr; Handle:integer):
  552.                                                                boolean;
  553.           {}
  554.           begin
  555.              PopUpSetActive(ListMenu,201,true);
  556.              SLLDestroy;
  557.              GoodbyeList := true;
  558.           end; { GoodbyeList }
  559.           {$F-}
  560.  
  561.           If the function returns false, the window will not close. The
  562.      first parameter passed to the function is a pointer to the MemoCfg
  563.      variable used to display the list. You can de-reference this
  564.      pointer to access the variable, for example:
  565.  
  566.           Total := MemoDetails^.ActiveNode
  567.  
  568.  
  569.           The demo file DEMMEM5.PAS shows the LaunchMemo function in all
  570.      its glory.
  571.  
  572. Saving Files in Hooks or on the Desktop
  573.  
  574.           IMPORTANT NOTE: Behind the scenes, a copy of the line
  575.      containing the cursor is maintained by Gold. As edits are made to
  576.      the memo, Gold simply updates the single line copy -- this offers
  577.      improved performance. When the user moves lines, the copy is posted
  578.      back to the original data and a copy of the new line is made. "Why
  579.      do I care" I hear you ask. Read On
  580.  
  581.           If you plan to save the memo in a hook, or as part of the
  582.      close function, you must instruct Gold to update the original data
  583.      with the current line using the following function:
  584.  
  585.      MemoStoreActiveLine(var MemoDetails: MemoCfg);
  586.  
  587.           Instructs Gold to write back (to the original data source) all
  588.      the edits performed on the active line, i.e. the line containing
  589.      the cursor.
  590.  
  591.      This procedure is used in DEMMEM5.PAS.
  592.  
  593. Error Handling
  594.  
  595.           The RunMemo function has the potential to fail. For example,
  596.      there may be insufficient memory to create the window. After
  597.      calling RunMemo , always call the function, LastMemoError to see if
  598.      the operation was successful.
  599.  
  600.      If LaunchMemo returns a zero, the window was not created.
  601.  
  602.